package com.yupi.springbootinit.manager;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.springbootinit.common.BaseResponse;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.common.ResultUtils;
import com.yupi.springbootinit.datasource.*;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.model.dto.post.PostQueryRequest;
import com.yupi.springbootinit.model.dto.search.SearchQueryRequest;
import com.yupi.springbootinit.model.dto.user.UserQueryRequest;
import com.yupi.springbootinit.model.entity.Picture;
import com.yupi.springbootinit.model.enums.SearchTypeEnum;
import com.yupi.springbootinit.model.vo.PostVO;
import com.yupi.springbootinit.model.vo.SearchVO;
import com.yupi.springbootinit.model.vo.UserVO;
import com.yupi.springbootinit.service.PictureService;
import com.yupi.springbootinit.service.PostService;
import com.yupi.springbootinit.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * 门面模式
 *
 * @author njy
 * @date 2023/5/2 16:00
 */
@Component
@Slf4j
public class SearchFacade {


    @Autowired
    private PictureDataSource pictureDataSource;

    @Autowired
    private PostDataSource postDataSource;

    @Autowired
    private UserDataSource userDataSource;

    @Autowired
    private DataSourceRegistry dataSourceRegistry;

    public SearchVO searchAll(@RequestBody SearchQueryRequest request,HttpServletRequest httpServletRequest) {
        String type = request.getType();
        String searchText = request.getSearchText();
        Long current = request.getCurrent();
        Long size = request.getSize();

        SearchTypeEnum enumByValue = SearchTypeEnum.getEnumByValue(type);
        //1如果type为空，拿所有数据
        if (enumByValue == null) {

            CompletableFuture<Page<Picture>> pictureFuture = CompletableFuture.supplyAsync(() -> {
                //图片
                Page<Picture> picture = pictureDataSource.doSearch(searchText, current, size);
                return picture;
            });

            CompletableFuture<Page<PostVO>> postFuture = CompletableFuture.supplyAsync(() -> {
                //帖子
                PostQueryRequest postQueryRequest = new PostQueryRequest();
                postQueryRequest.setSearchText(searchText);
                Page<PostVO> postVOPage = postDataSource.doSearch(searchText, current, size);
                return postVOPage;
            });

            CompletableFuture<Page<UserVO>> userFuture = CompletableFuture.supplyAsync(() -> {
                //用户
                UserQueryRequest userQueryRequest = new UserQueryRequest();
                userQueryRequest.setUserName(searchText);
                Page<UserVO> userVOPage = userDataSource.doSearch(searchText, current, size);
                return userVOPage;
            });
            //阻塞，三个完成之后才走下一步
            CompletableFuture.allOf(pictureFuture, postFuture, userFuture).join();
            //聚合
            SearchVO searchVO = null;
            try {
                searchVO = SearchVO.builder()
                        .postVOList(postFuture.get().getRecords())
                        .userVOList(userFuture.get().getRecords())
                        .pictureList(pictureFuture.get().getRecords())
                        .build();
                return searchVO;
            } catch (Exception e) {
                log.error("聚合查询异常，error:{}", e);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "聚合查询异常");
            }
        } else {
            //2type不为空
            SearchVO searchVO = new SearchVO();
            DataSource dataSource = dataSourceRegistry.getDataSourceByType(type);
            Page<?> tPage = dataSource.doSearch(searchText, current, size);
            searchVO.setDataList(tPage.getRecords());
            return searchVO;
        }
    }
}
